package cc.mango.android.chartdata;

import java.net.SocketTimeoutException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.content.Context;

import cc.mango.android.dto.StkDaily;
import cc.mango.android.dto.StkIntraday;

import cc.mango.common.FinalKey;
import cc.mango.data.DataHelper;
import cc.telecomdigital.tdstock.Framework.UniqueItem.TDStockLog;
import cc.telecomdigital.tdstock.activity.chart.NvChart;

public class ChartDataHelper
{

	private String						stockCode;										//股票、指数或者外汇的代码
	private Context					context;
	private String						activationCode;

	private List<StkIntraday>			oneDayDataList;
	private List<StkIntraday>			oneWeekDataList;

	private List<StkDaily>				oneMonthDataList;
	private List<StkDaily>				threeMonthDataList;
	private List<StkDaily>				sixMonthDataList;
	private List<StkDaily>				oneYearDataList;
	private List<StkDaily>				twoYearDataList;

	private boolean					isCalSmaAndRsi	= false;								//当前数据是否计算过SMA10,SMA50,RSI

	private Map<String, List<StkDaily>>	dailyMap		= new HashMap<String, List<StkDaily>>();

	public ChartDataHelper(String stockCode, Context context,
			String activationCode)
	{

		this.stockCode = stockCode;
		this.context = context;
		this.activationCode = activationCode;

	}

	//根据时间类型获取数据
	public List getDataList(String dateType) throws SocketTimeoutException
	{

		List dataList = null;

		int count = 0;

		if (FinalKey.INTRADAY_DATETYPE_TODAY.equals(dateType))
		{ //一天

			while (count < 4 && (dataList == null || dataList.size() == 0))
			{ //如果失败，继续尝试连接，共四次尝试

				count++;

				dataList = getOneDayListByCode();
			}

			return dataList;

		}
		else if (FinalKey.INTRADAY_DATETYPE_WEEK.equals(dateType))
		{//一周

			while (count < 4 && (dataList == null || dataList.size() == 0))
			{

				count++;

				dataList = getOneWeekListByCode();

			}

			return dataList;

		}

		//如果是Daily数据，先取两年的数据，把SMA10，SMA50，RSI数据全部计算出来
		if (!isCalSmaAndRsi)
		{ //当前数据是否计算过SMA10,SMA50,RSI

			long t1 = System.currentTimeMillis();

			//如果是Daily数据，先取两年的数据
			while (count < 4 && (dataList == null || dataList.size() == 0))
			{

				count++;

				dataList = getTwoYearListByCode();

			}

			long t2 = System.currentTimeMillis();

			TDStockLog.d("Print_Info", "===== get date time is " + (t2 - t1));

			if (dataList == null || dataList.size() == 0)
			{

				return null;

			}
			else
			{

				twoYearDataList = dataList;

				t1 = System.currentTimeMillis();
				dataList = calSma10(dataList, 10); //计算SMA10数据
				t2 = System.currentTimeMillis();

				TDStockLog.d("Print_Info", "===== cal sma10 time is " + (t2 - t1));

				t1 = System.currentTimeMillis();
				dataList = calSma50(dataList, 50); //计算SMA50数据
				t2 = System.currentTimeMillis();
				TDStockLog.d("Print_Info", "=====  cal sma50 time is "
								+ (t2 - t1));

				t1 = System.currentTimeMillis();
				dataList = calRsi(dataList, 14); //计算SMA10数据
				t2 = System.currentTimeMillis();
				TDStockLog.d("Print_Info", "=====  cal rsi time is " + (t2 - t1));

				twoYearDataList = dataList;

				isCalSmaAndRsi = true;
			}

		}

		dataList = null;
		count = 0;

		if (FinalKey.DAILY_DATETYPE_MONTH.equals(dateType))
		{//从2年数据中取出1月数据

			while (count < 4 && (dataList == null || dataList.size() == 0))
			{

				count++;

				dataList = getOneMonthListByCode();
			}

			return dataList;

		}
		else if (FinalKey.DAILY_DATETYPE_3MONTHS.equals(dateType))
		{//从2年数据中取出3月数据

			while (count < 4 && (dataList == null || dataList.size() == 0))
			{

				count++;

				dataList = getThreeMonthListByCode();
			}

			return dataList;

		}
		else if (FinalKey.DAILY_DATETYPE_6MONTHS.equals(dateType))
		{//从2年数据中取出6月数据

			while (count < 4 && (dataList == null || dataList.size() == 0))
			{

				count++;

				dataList = getSixMonthListByCode();
			}

			return dataList;

		}
		else if (FinalKey.DAILY_DATETYPE_YEAR.equals(dateType))
		{//从2年数据中取出1年数据

			while (count < 4 && (dataList == null || dataList.size() == 0))
			{

				count++;

				dataList = getOneYearListByCode();
			}

			return dataList;

		}
		else
		{

			while (count < 4 && (dataList == null || dataList.size() == 0))
			{//从2年数据中取出2年数据

				count++;

				dataList = getTwoYearListByCode();
			}

			return dataList;

		}

	}

	private List<StkIntraday> getOneDayListByCode()
			throws SocketTimeoutException
	{//取1天数据

		if (oneDayDataList != null && oneDayDataList.size() != 0)
		{

			return oneDayDataList;
		}

		//下载数据
		List<StkIntraday> dataList = DataHelper.getStkIntraListByCode(
				stockCode, FinalKey.INTRADAY_DATETYPE_TODAY, context,
				activationCode);

		oneDayDataList = dataList;
		return dataList;
	}

	public List<StkIntraday> getOneWeekListByCode()
			throws SocketTimeoutException
	{//取1周数据

		if (oneWeekDataList != null && oneWeekDataList.size() != 0)
		{

			return oneWeekDataList;
		}

		//下载数据
		List<StkIntraday> dataList = DataHelper.getStkIntraListByCode(
				stockCode, FinalKey.INTRADAY_DATETYPE_WEEK, context,
				activationCode);

		oneWeekDataList = dataList;
		return dataList;
	}

	private List<StkDaily> getOneMonthListByCode()
			throws SocketTimeoutException
	{//取1月数据

		if (oneMonthDataList != null && oneMonthDataList.size() != 0)
		{

			return oneMonthDataList;
		}

		//下载数据
		List<StkDaily> dataList = DataHelper.sortOut(stockCode, dailyMap,
				FinalKey.DAILY_DATETYPE_MONTH, context, null,
				activationCode);

		oneMonthDataList = dataList;

		return dataList;
	}

	private List<StkDaily> getThreeMonthListByCode()
			throws SocketTimeoutException
	{//取3月数据

		if (threeMonthDataList != null && threeMonthDataList.size() != 0)
		{

			return threeMonthDataList;
		}

		//下载数据
		List<StkDaily> dataList = DataHelper.sortOut(stockCode, dailyMap,
				FinalKey.DAILY_DATETYPE_3MONTHS, context, null,
				activationCode);

		threeMonthDataList = dataList;
		return dataList;
	}

	private List<StkDaily> getSixMonthListByCode()
			throws SocketTimeoutException
	{//取6月数据

		if (sixMonthDataList != null && sixMonthDataList.size() != 0)
		{

			return sixMonthDataList;
		}

		//下载数据
		List<StkDaily> dataList = DataHelper.sortOut(stockCode, dailyMap,
				FinalKey.DAILY_DATETYPE_6MONTHS, context, null,
				activationCode);

		sixMonthDataList = dataList;
		return dataList;
	}

	private List<StkDaily> getOneYearListByCode()
			throws SocketTimeoutException
	{//取1年数据

		if (oneYearDataList != null && oneYearDataList.size() != 0)
		{

			return oneYearDataList;
		}

		//下载数据
		List<StkDaily> dataList = DataHelper
				.sortOut(stockCode, dailyMap, FinalKey.DAILY_DATETYPE_YEAR,
						context, null, activationCode);

		oneYearDataList = dataList;
		return dataList;
	}

	private List<StkDaily> getTwoYearListByCode()
			throws SocketTimeoutException
	{//取2年数据

		if (twoYearDataList != null && twoYearDataList.size() != 0)
		{

			return twoYearDataList;
		}

		//下载数据
		List<StkDaily> dataList = DataHelper.sortOut(stockCode, dailyMap,
				FinalKey.DAILY_DATETYPE_2YEARS, context, null,
				activationCode);

		twoYearDataList = dataList;

		return dataList;
	}

	//计算SMA10
	private List<StkDaily> calSma10(List<StkDaily> dataList, int count)
			throws SocketTimeoutException
	{

		int size = dataList.size();

		List<StkDaily> twoYearsList = this.getTwoYearListByCode();

		int maxSize = twoYearsList.size();

		if (twoYearsList == null || twoYearsList.size() == 0)
		{

			return dataList;
		}

		double lastSum = 0;//上一次count数之和

		for (int i = 0; i < count; i++)
		{

			int index = maxSize - 1 - i;

			if (index < 0)
			{//说明上市不到count天，数据量少于count

				return dataList;

			}

			lastSum += twoYearsList.get(index).getClose();

		}

		dataList.get(size - 1).setSma10(lastSum / count);

		for (int i = 0; i < size - 1; i++)
		{

			int lastIndex = maxSize - 1 - i;

			int firstIndex = maxSize - 1 - i - count;

			if (firstIndex < 0)
			{

				return dataList;

			}

			lastSum = lastSum - twoYearsList.get(lastIndex).getClose()
					+ twoYearsList.get(firstIndex).getClose();

			dataList.get(size - i - 2).setSma10(lastSum / count);
		}

		return dataList;
	}

	//计算SMA50
	private List<StkDaily> calSma50(List<StkDaily> dataList, int count)
			throws SocketTimeoutException
	{

		int size = dataList.size();

		List<StkDaily> twoYearsList = this.getTwoYearListByCode();

		int maxSize = twoYearsList.size();

		if (twoYearsList == null || twoYearsList.size() == 0)
		{

			return dataList;
		}

		double lastSum = 0;//上一次count数之和

		for (int i = 0; i < count; i++)
		{

			int index = maxSize - 1 - i;

			if (index < 0)
			{//说明上市不到count天，数据量少于count

				return dataList;

			}

			lastSum += twoYearsList.get(index).getClose();

		}

		dataList.get(size - 1).setSma50(lastSum / count);

		for (int i = 0; i < size - 1; i++)
		{

			int lastIndex = maxSize - 1 - i;

			int firstIndex = maxSize - 1 - i - count;

			if (firstIndex < 0)
			{

				return dataList;

			}

			lastSum = lastSum - twoYearsList.get(lastIndex).getClose()
					+ twoYearsList.get(firstIndex).getClose();

			dataList.get(size - i - 2).setSma50(lastSum / count);
		}

		return dataList;
	}

	//计算RSI
	private List<StkDaily> calRsi(List<StkDaily> dataList, int count)
			throws SocketTimeoutException
	{

		int size = dataList.size();

		double lastClose = 0;
		double currentClose = 0;
		double subClose = 0;

		double riseCloseSum = 0;

		double fallCloseSum = 0;

		double RS = 0;
		double RSI = 0;

		List<StkDaily> twoYearsList = this.getTwoYearListByCode();

		int maxSize = twoYearsList.size();

		if (twoYearsList == null || twoYearsList.size() == 0)
		{

			return dataList;
		}

		for (int i = 0; i < count; i++)
		{

			int index = maxSize - 1 - i;

			if (index - 1 < 0)
			{//说明上市不到count天，数据量少于count

				return dataList;

			}

			currentClose = twoYearsList.get(index).getClose();

			lastClose = twoYearsList.get(index - 1).getClose();

			subClose = currentClose - lastClose;

			if (subClose < 0)
			{

				fallCloseSum += subClose;
			}
			else
			{

				riseCloseSum += subClose;
			}

		}

		RS = riseCloseSum / Math.abs(fallCloseSum);

		RSI = 100 - 100 / (1 + RS);

		dataList.get(size - 1).setRsi(RSI);

		for (int i = 0; i < size - 1; i++)
		{

			int lastIndex = maxSize - 1 - i;

			int firstIndex = maxSize - 1 - i - count;

			if (firstIndex - 1 < 0)
			{

				return dataList;

			}

			currentClose = twoYearsList.get(lastIndex).getClose();

			lastClose = twoYearsList.get(lastIndex - 1).getClose();

			subClose = currentClose - lastClose;

			if (subClose < 0)
			{

				fallCloseSum -= subClose;
			}
			else
			{

				riseCloseSum -= subClose;
			}

			currentClose = twoYearsList.get(firstIndex).getClose();

			lastClose = twoYearsList.get(firstIndex - 1).getClose();

			subClose = currentClose - lastClose;

			if (subClose < 0)
			{

				fallCloseSum += subClose;
			}
			else
			{

				riseCloseSum += subClose;
			}

			RS = riseCloseSum / Math.abs(fallCloseSum);

			RSI = 100 - 100 / (1 + RS);

			dataList.get(size - i - 2).setRsi(RSI);

		}

		/*	label: for(int i = 0; i < size;i++){
				
				for(int j = 0; j < count ; j++){
					
					int index = maxSize - size + i - j ;
					
					if(index - 1< 0){
						
		//					return dataList;
						
						fallCloseSum = 0;
						
						riseCloseSum = 0;
						
						continue label;
						
					}
					
					currentClose = twoYearsList.get(index).getClose();
					
					lastClose = twoYearsList.get(index - 1).getClose();
					
					subClose = currentClose - lastClose;
					
					if(subClose < 0){
						
						fallCloseSum += subClose;
					}
					else{
						
						riseCloseSum += subClose;
					}
				}
				
				RS = riseCloseSum / Math.abs(fallCloseSum);
							
		//			RSI = 100 * ( RS / (1 + RS));//RSI = 100 - 100/ (1 + RS);
				RSI = 100 - 100/ (1 + RS);
				
				dataList.get(i).setRsi(RSI);
				
				fallCloseSum = 0;
				
				riseCloseSum = 0;
				
			}*/

		return dataList;
	}

}